package com.gjt.serverSocket;


import java.io.*;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 重定向器： 是特殊用途的http服务器
 *
 * @author Guojt
 * @date 2024/9/9 7:49
 */
public class Redirector {
    private static final Logger logger = Logger.getLogger("Redirector");

    private final int port;

    private final String newSite;

    public Redirector(int port, String newSite) {
        this.port = port;
        this.newSite = newSite;
    }

    public void start() {
        try (ServerSocket ss = new ServerSocket(port)) {
            logger.info("Redirector connections on port" + ss.getLocalPort() + "to" + newSite);
            while (true) {
                try {
                    Socket accept = ss.accept();
                    new RedirectorThread(accept).start();
                } catch (IOException e) {
                   logger.warning("Exception accepting connection");
                }catch (RuntimeException ex){
                    logger.log(Level.SEVERE,"Unexpected error",ex);
                }
            }
        } catch (BindException e) {
           logger.log(Level.SEVERE,"Could not start server.", e);
        }catch (IOException ex){
            logger.log(Level.SEVERE, "Error opening server socket", ex);
        }
    }

    private class RedirectorThread extends Thread {
        private final Socket connection;

        public RedirectorThread(Socket connection) {
            this.connection = connection;
        }

        @Override
        public void run() {
            try {
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8));
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

                // 只读取第一行，我们需要的全部内容
                StringBuilder request = new StringBuilder(80);
                while (true) {
                    int c = in.read();
                    if (c == '\r' || c == '\n' || c == -1) break;
                    request.append((char) c);
                }

                String get = request.toString();
                String[] pieces = get.split("\\w*");
                String theFile = pieces[1];

                // 如果是http/1.0 或者以后的版本， 则发送一个mime 首部
                if (get.indexOf("http") != -1) {
                    out.write("HTTP/1.0 302 FOUND \r\n");
                    Date now = new Date();
                    out.write("Date:" + now + "\r\n");
                    out.write("Server: Redirector 1.1\r\n");
                    out.write("Location:" + newSite + theFile + "\r\n");
                    out.write("Content-type: text/html\r\n\r\n");
                    out.flush();
                }

                // 并不是所有的浏览器都支持重定向，需要生成html 指出文档转移到哪里
                out.write("<HTML><HEAD><TITLE>Document Moved</TITLE></HEAD><BODY>\r\n");
                out.write("<BODY><H1>Document moved</H1>\r\n");
                out.write("The document " + newSite + theFile
                        + "has moved to\r\n<A HREF=\"" + newSite + theFile + "\">"
                        + newSite + theFile + "</A>.\r\n Please update your bookmarks<P>");
                out.write("</BODY></HTML>\r\n");
                out.flush();
                logger.info(Level.INFO + "Redirected" + connection.getRemoteSocketAddress());
            } catch (IOException e) {
                logger.log(Level.WARNING, "ERROR talking tp" + connection.getRemoteSocketAddress());
            } finally {
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     *  会读取新网站得url (把这些连接重定向到这个新网站)和要监听得本地端口
     * @param args
     */
    public static void main(String[] args) {
        int thePort;
        String theSite;

        try {
            theSite = args[0];
            // 删除末尾斜线
            if(theSite.endsWith("/")){
                theSite = theSite.substring(0, theSite.length() - 1);
            }
        } catch (Exception e) {
            System.out.println("Usage: java Redirector http://www.newsite.com/ port");
            return;
        }

        try {
            thePort = Integer.parseInt(args[1]);
        } catch (NumberFormatException e) {
            thePort = 80;
        }
        new Redirector(thePort, theSite).start();
    }
}
